#ifndef __GDL_RESOURCE_HPP__
#define __GDL_RESOURCE_HPP__

namespace gdl
{

	class ResourceBase
	{
	public:
		////////////////////////////////////////////////////////////
		/// Default constructor.
		////////////////////////////////////////////////////////////
		ResourceBase();
		////////////////////////////////////////////////////////////
		/// Copy constructor.
		////////////////////////////////////////////////////////////
		ResourceBase(ResourceBase const & right);

		////////////////////////////////////////////////////////////
		/// Default destructor.
		////////////////////////////////////////////////////////////
		virtual ~ResourceBase();
		////////////////////////////////////////////////////////////
		/// Overloading of the assignment operator.
		////////////////////////////////////////////////////////////
		ResourceBase& operator=(ResourceBase const &);

	protected:
		////////////////////////////////////////////////////////////
		/// Check if the data pointer can be destroyed.
		////////////////////////////////////////////////////////////
		void check_destroy();

	private:
		////////////////////////////////////////////////////////////
		/// Destroy the data pointer.
		////////////////////////////////////////////////////////////
		virtual void destroy() = 0;
		////////////////////////////////////////////////////////////
		/// Increase the reference counter.
		////////////////////////////////////////////////////////////
		void incCount();
		////////////////////////////////////////////////////////////
		/// Decrease the reference counter.
		////////////////////////////////////////////////////////////
		void decCount();

		int* counter_;
	};

	template <typename Type>
	class Resource : private ResourceBase
	{
	public:
		////////////////////////////////////////////////////////////
		/// Explicit constructor.
		///
		/// \param[in] val The pointer on a resource.
		////////////////////////////////////////////////////////////
		explicit Resource(Type* val);
		////////////////////////////////////////////////////////////
		/// Copy constructor.
		///
		/// \param[in] right Resource to copy.
		////////////////////////////////////////////////////////////
		Resource(Resource const &);
		////////////////////////////////////////////////////////////
		/// Overloading of the assignment operator.
		///
		/// \return An reference on the Resource instance.
		////////////////////////////////////////////////////////////
		Resource& operator=(Resource const &);
		////////////////////////////////////////////////////////////
		/// Default destructor.
		////////////////////////////////////////////////////////////
		virtual ~Resource();

		////////////////////////////////////////////////////////////
		/// Check if the resource is valid.
		///
		/// \return If valid, true is returned.
		/// Otherwise, false is returned.
		////////////////////////////////////////////////////////////
		bool	isValid() const;

		////////////////////////////////////////////////////////////
		/// Overloading of the member operator.
		////////////////////////////////////////////////////////////
		Type* operator->();
		////////////////////////////////////////////////////////////
		/// Overloading of the indirection operator.
		////////////////////////////////////////////////////////////
		Type& operator*();

	protected:
		Type* data_; //Template type to point the data

		////////////////////////////////////////////////////////////
		/// Reset the data.
		////////////////////////////////////////////////////////////
		void HardReset();

	private:
		////////////////////////////////////////////////////////////
		/// Destroy the data.
		////////////////////////////////////////////////////////////
		virtual void destroy();
	};
}

#endif /* __GDL_RESOURCE_HPP__ */
